#include "stdafx.h"
#include "MemTxtFile.h"
#include "ZCmnFile.h"
#include "GlobalDefs.h"

CMemTxtFile::CMemTxtFile(string _FileName/* = ""*/)
: m_IsInitOK(false)
, m_IsAttached(false)
, m_pFileBuf(NULL)
, m_pFileBufEnd(NULL)
, m_FileLen(0)
, m_pNextLineBegin(NULL)
{
	if (!_FileName.empty()) {
		OpenTxtFile(_FileName);
	}
}

CMemTxtFile::~CMemTxtFile(void)
{
	if (!m_IsAttached && m_IsInitOK) {
		char* _pBuf = (char*)m_pFileBuf;
		SAFE_DELETE_ARRAY(_pBuf);
		m_pFileBuf = NULL;
	}
}

bool CMemTxtFile::AttachBuf(LPVOID _pBuf, int _Len)
{
	CloseTxtFile();
	if (!_pBuf) {
		return false;
	}
	m_IsAttached = true;
	m_FileLen = _Len;
	m_pFileBuf = _pBuf;
	m_pNextLineBegin = (char*)m_pFileBuf;
	m_pFileBufEnd = (LPVOID)((DWORD)m_pFileBuf + m_FileLen);
	m_IsInitOK = true;
	return true;
}

void CMemTxtFile::Reset()
{
	m_IsAttached = false;
	m_IsInitOK = false;
	m_pFileBuf = NULL;
	m_pFileBufEnd = NULL;
	m_FileLen = 0;
	m_pNextLineBegin = NULL;
}

void CMemTxtFile::DetachBuf()
{
	Reset();
}

void CMemTxtFile::CloseTxtFile()
{
	if (!m_IsAttached && m_IsInitOK) {
		char* _pBuf = (char*)m_pFileBuf;
		SAFE_DELETE_ARRAY(_pBuf);
		m_pFileBuf = NULL;
	}
	Reset();
}

bool CMemTxtFile::OpenTxtFile(string _FileName)
{
	CloseTxtFile();

	ZCmnFile _File;
	if (!(m_IsInitOK = _File.OpenFile(_FileName,false,false,GENERIC_READ))) {
		return false;
	}
	m_FileLen = _File.ZFileGetSize();
	if (m_FileLen > 0) {
		m_pFileBuf = new char[m_FileLen+1];
		m_pNextLineBegin = (char*)m_pFileBuf;
		m_pFileBufEnd = (LPVOID)((DWORD)m_pFileBuf + m_FileLen);
		if (!_File.ReadFile(m_pFileBuf,m_FileLen)) {
			Reset();
		}
	}
	_File.CloseFile();
	return m_IsInitOK;
}

DWORD CMemTxtFile::GetMemTxtFileSize()
{
	return m_FileLen;
}

bool CMemTxtFile::GetNextLine(string& _LineStr)
{
	char* _pNextLine;
	char* _pNextChar;
	int _CRLFNum = 1;
	if (m_IsInitOK && m_pFileBuf && m_pNextLineBegin && !IsEOF()) {
		_pNextChar = m_pNextLineBegin;
		_pNextLine = m_pNextLineBegin;
		int _StrLen = 0;
		while (_pNextChar < m_pFileBufEnd && (*_pNextChar != '\r' && *_pNextChar != '\n'))  {
			_pNextChar++;
		}
		if (_pNextChar < m_pFileBufEnd) {
			if (*_pNextChar == '\r' && (_pNextChar+1) < m_pFileBufEnd && *(_pNextChar+1) == '\n') {
				_pNextChar++;
				_CRLFNum++;
			}
		}

		m_pNextLineBegin = _pNextChar+1;
		_StrLen = m_pNextLineBegin - _pNextLine - _CRLFNum;
		_LineStr = _StrLen?string(_pNextLine,_StrLen):"";
		return true;
	}
	return false;
}

bool CMemTxtFile::WriteToFile(string _FileName, bool _IsAppend/* = false*/)
{
	if (m_IsInitOK && m_pFileBuf && GetMemTxtFileSize()) {
		ZCmnFile _OutFile;
		if (_OutFile.OpenFile(_FileName,true,!_IsAppend)) {
			if (_IsAppend) {
				_OutFile.ZFileSeek(0,FILE_END);
			}
			return _OutFile.WriteFile(m_pFileBuf,GetMemTxtFileSize());
		}
	}
	return false;
}